/* ----------------------------------------------------------------------------
* File: skype_events.h
*
* Desc: Stuffs for handling of the Skype events
*
* Created: 24/12/2010, by Alexey Korshunov
* ---------------------------------------------------------------------------- */
#ifndef _SKYPE_EVENTS_H_
#define _SKYPE_EVENTS_H_

#include <atlbase.h>
#include <atlcom.h>

#include "main.h"

using namespace SKYPE4COMLib;


static _ATL_FUNC_INFO AttachmentStatusInfo =  {CC_STDCALL,VT_EMPTY,1,{VT_I4}};
static _ATL_FUNC_INFO CommandInfo = {CC_STDCALL,VT_EMPTY,1,{VT_DISPATCH|VT_BYREF}};
static _ATL_FUNC_INFO ReplyInfo = {CC_STDCALL,VT_EMPTY,1,{VT_DISPATCH|VT_BYREF}};
static _ATL_FUNC_INFO ErrorInfo = {CC_STDCALL,VT_EMPTY,3,{VT_DISPATCH|VT_BYREF,VT_I4,VT_BSTR}};
static _ATL_FUNC_INFO ConnectionStatusInfo = {CC_STDCALL,VT_EMPTY,1,{VT_I4}};
static _ATL_FUNC_INFO UserStatusInfo = {CC_STDCALL,VT_EMPTY,1,{VT_I4}};
static _ATL_FUNC_INFO OnlineStatusInfo = {CC_STDCALL,VT_EMPTY,2,{VT_DISPATCH|VT_BYREF,VT_I4}};
static _ATL_FUNC_INFO CallStatusInfo = {CC_STDCALL,VT_EMPTY,2,{VT_DISPATCH|VT_BYREF,VT_I4}};
static _ATL_FUNC_INFO CallHistoryInfo = {CC_STDCALL,VT_EMPTY,0,{VT_EMPTY}};
static _ATL_FUNC_INFO MuteInfo = {CC_STDCALL,VT_EMPTY,1,{VT_BOOL}};
static _ATL_FUNC_INFO MessageStatusInfo = {CC_STDCALL,VT_EMPTY,2,{VT_DISPATCH|VT_BYREF,VT_I4}};
static _ATL_FUNC_INFO MessageHistoryInfo = {CC_STDCALL,VT_EMPTY,1,{VT_BSTR}};


/************************************************************************/
/* Class CSkypeEventListener() for listening Skype events                */
/************************************************************************/
//class CSkypeEventListener : public IDispEventSimpleImpl<1, CSkypeEventListener, &__uuidof(_ISkypeEvents)>
//{
//public:
//	// Constructor
//	CSkypeEventListener(SkypeEnv *pEnv) : m_pSkypeEnv(pEnv) {};
//
//	// Sink map
//	BEGIN_SINK_MAP(CSkypeEventListener)
//		//SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 1, &Command,  &CommandInfo)
//		//SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 2, &Reply,  &ReplyInfo)
//		SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 3, &Error,  &ErrorInfo)
//		SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 4, &AttachmentStatus,  &AttachmentStatusInfo)
//		SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 5, &ConnectionStatus,  &ConnectionStatusInfo)
//		SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 6, &UserStatus,  &UserStatusInfo)
//		SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 7, &OnlineStatus,  &OnlineStatusInfo)
//		//SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 8, &CallStatus,  &CallStatusInfo)
//		//SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 10, &Mute,  &MuteInfo)
//		SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 11, &MessageStatus,  &MessageStatusInfo)
//		SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 12, &MessageHistory,  &MessageHistoryInfo)
//	END_SINK_MAP()
//
//	//void __stdcall Command(ICommand* pCommand) {
//
//	//	_tprintf(_T("C(%d): %s\n"), pCommand->GetId(), (LPCTSTR)pCommand->GetCommand());
//
//	//}
//
//	//void __stdcall Reply(ICommand* pCommand) {
//
//	//	_tprintf(_T("R(%d): %s\n"), pCommand->GetId(), (LPCTSTR)pCommand->GetReply());
//
//	//}
//
//	/************************************************************************/
//	/* Error handler                                                        */
//	/************************************************************************/
//	void __stdcall Error(ICommand* pCommand, LONG Number, BSTR Description)
//	{
//		OutputDebugString(TEXT("Error(%d): %s", pCommand->GetId(), (LPCTSTR)pCommand->GetReply()));
//	}
//
//
//	/************************************************************************/
//	/* Handler for attachment status events                                 */
//	/************************************************************************/
//	void __stdcall AttachmentStatus(TAttachmentStatus Status) 
//	{ 
//		ISkypePtr pSkype = m_pSkypeEnv->skypeInfo.pSkype;
//
//		_bstr_t strStatus = pSkype->Convert->AttachmentStatusToText(Status);
//		MyOutputDebugString(TEXT("Attachment status %d (%s)"), Status, (LPCTSTR)strStatus);
//
//		if (Status == TAttachmentStatus::apiAttachAvailable || 
//			Status == TAttachmentStatus::apiAttachNotAvailable)
//		{
//			// Try to attach again
//			pSkype->Attach(6, VARIANT_FALSE);
//		}
//	}
//
//
//	/************************************************************************/
//	/* Handler for connection events                                        */
//	/************************************************************************/
//	void __stdcall ConnectionStatus(TConnectionStatus Status)
//	{
//		ISkypePtr pSkype = m_pSkypeEnv->skypeInfo.pSkype;
//
//		_bstr_t strStatus = pSkype->Convert->ConnectionStatusToText(Status);
//		MyOutputDebugString(TEXT("Connection status %d (%s)"), Status, (LPCTSTR)strStatus);
//	}
//
//
//	/************************************************************************/
//	/* Handler for user status events                                       */
//	/************************************************************************/
//	void __stdcall UserStatus(TUserStatus Status)
//	{
//		ISkypePtr pSkype = m_pSkypeEnv->skypeInfo.pSkype;
//
//		_bstr_t strStatus = pSkype->Convert->UserStatusToText(Status);
//		MyOutputDebugString(TEXT("User status %d (%s)"), Status, (LPCTSTR)strStatus);
//	}
//
//
//	/************************************************************************/
//	/* Handler for online user status                                       */
//	/************************************************************************/
//	void __stdcall OnlineStatus(IUser* pUser, TOnlineStatus Status)
//	{
//		OutputDebugString(TEXT("User %s status %d", (LPCTSTR)pUser->GetHandle(), Status));
//	}
//
//
//	/************************************************************************/
//	/* Handler for call status                                              */
//	/************************************************************************/
//	//void __stdcall CallStatus(ICall* pCall, TCallStatus Status)
//	//{
//	//	_tprintf(_T("Call %d status %d\n"), pCall->GetId(), Status);
//	//}
//
//
//	/************************************************************************/
//	/* Handler for call history                                             */
//	/************************************************************************/
//	//void __stdcall CallHistory()
//	//{
//	//	_tprintf(_T("Call history changed\n"));
//	//}
//
//
//	/************************************************************************/
//	/* Mute events                                                          */
//	/************************************************************************/
//	//void __stdcall Mute(VARIANT_BOOL Status)
//	//{      
//	//	if (Status == VARIANT_TRUE) {
//
//	//		_tprintf(_T("Mute on\n"));
//
//	//	} else {
//
//	//		_tprintf(_T("Mute off\n"));
//
//	//	}
//	//}
//
//
//	/************************************************************************/
//	/* Message status events                                                */
//	/************************************************************************/
//	void __stdcall MessageStatus(IChatMessage* pMessage, TChatMessageStatus Status)
//	{
//		ISkypePtr pSkype = m_pSkypeEnv->skypeInfo.pSkype;
//		ChatInfo *pChatInfo = &m_pSkypeEnv->chatInfo;
//
//		_bstr_t strStatus = pSkype->Convert->ChatMessageStatusToText(Status);
//#ifdef _DEBUG
//		_tprintf(_T("%d"), pMessage->GetId());
//		MyOutputDebugString(TEXT("Message:"));
//		MyOutputDebugString(TEXT("	Id = %d"), pMessage->GetId());
//		MyOutputDebugString(TEXT("	Status - %d (%s)"), Status, strStatus);
//		MyOutputDebugString(TEXT("	ChatName - %s"), pMessage->ChatName);
//#endif
//		//OutputDebugString(TEXT("	", pMessage->))
//		//_tprintf(_T("Message %d status %d\n"), pMessage->GetId(), Status);
//
//		// Ignore cmsSent and cmsRead messages
//		if (Status != TChatMessageStatus::cmsSent &&
//			Status != TChatMessageStatus::cmsRead)
//		{
//			// check chat, it's identical chat
//			if (!_tcscmp(pMessage->ChatName, pChatInfo->pChat->GetName()))
//			{
//				// get message info
//				MessageInfo msgInfo;
//				_bstr_t handle = pMessage->GetFromHandle();
//				msgInfo.Id = pMessage->GetId();
//				msgInfo.body = pMessage->GetBody();
//				msgInfo.msgStatus = pMessage->GetStatus();
//				msgInfo.msgType = pMessage->GetType();
//
//				// add message into the map
//				EnterCriticalSection(&pChatInfo->csMsg);
//				pChatInfo->msgMap[handle].push_back(msgInfo);
//				pChatInfo->countMessages++;
//				LeaveCriticalSection(&pChatInfo->csMsg);
//			}
//			// other chat - get commands or discussion
//			else
//			{
//				MessageInfo msgInfo;
//				msgInfo.Id = pMessage->GetId();
//				msgInfo.body = pMessage->GetBody();
//				msgInfo.msgStatus = pMessage->GetStatus();
//				msgInfo.msgType = pMessage->GetType();
//
//				// add message into the command list
//				EnterCriticalSection(&m_pSkypeEnv->csCommands);
//				m_pSkypeEnv->listCommands.push_back(msgInfo);
//				LeaveCriticalSection(&m_pSkypeEnv->csCommands);
//			}
//		}
//	}
//
//
//	/************************************************************************/
//	/* Message history events                                               */
//	/************************************************************************/
//	void __stdcall MessageHistory(BSTR Username)
//	{
//		OutputDebugString(TEXT("Message history changed %s", (LPCTSTR)_bstr_t(Username)));
//		//_tprintf(_T("Message history changed %s\n"), (LPCTSTR)_bstr_t(Username));
//	}
//
//protected:
//private:
//	SkypeEnv *m_pSkypeEnv;
//};


class CSkypeEventListener : public IDispEventSimpleImpl<1,CSkypeEventListener , &__uuidof(_ISkypeEvents)>

{

public:

	CSkypeEventListener(SkypeEnv *pEnv) : m_pSkypeEnv(pEnv) {};

	BEGIN_SINK_MAP(CSkypeEventListener)

		//SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 1, &Command,  &CommandInfo)

		//SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 2, &Reply,  &ReplyInfo)

		SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 3, &Error,  &ErrorInfo)

		SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 4, &AttachmentStatus,  &AttachmentStatusInfo)

		SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 5, &ConnectionStatus,  &ConnectionStatusInfo)

		SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 6, &UserStatus,  &UserStatusInfo)

		SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 7, &OnlineStatus,  &OnlineStatusInfo)

		SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 8, &CallStatus,  &CallStatusInfo)

		SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 10, &Mute,  &MuteInfo)

		SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 11, &MessageStatus,  &MessageStatusInfo)

		SINK_ENTRY_INFO(1, __uuidof(_ISkypeEvents), 12, &MessageHistory,  &MessageHistoryInfo)

	END_SINK_MAP()



	//void __stdcall Command(ICommand* pCommand) {

	//	_tprintf(_T("C(%d): %s\n"), pCommand->GetId(), (LPCTSTR)pCommand->GetCommand());

	//}

	//void __stdcall Reply(ICommand* pCommand) {

	//	_tprintf(_T("R(%d): %s\n"), pCommand->GetId(), (LPCTSTR)pCommand->GetReply());

	//}

	void __stdcall Error(ICommand* pCommand, LONG Number, BSTR Description) {

		_tprintf(_T("E(%d): %s\n"), pCommand->GetId(), (LPCTSTR)pCommand->GetReply());

	}

	void __stdcall AttachmentStatus(TAttachmentStatus Status) {

		_tprintf(_T("Attachment status %d\n"), Status);

	}

	void __stdcall ConnectionStatus(TConnectionStatus Status) {

		_tprintf(_T("Connection status %d\n"), Status);

	}

	void __stdcall UserStatus(TUserStatus Status) {

		_tprintf(_T("User status %d\n"), Status);

	}

	void __stdcall OnlineStatus(IUser* pUser, TOnlineStatus Status) {

		_tprintf(_T("User %s status %d\n"), (LPCTSTR)pUser->GetHandle(), Status);

	}

	void __stdcall CallStatus(ICall* pCall, TCallStatus Status) {

		_tprintf(_T("Call %d status %d\n"), pCall->GetId(), Status);

	}

	void __stdcall CallHistory() {

		_tprintf(_T("Call history changed\n"));

	}

	void __stdcall Mute(VARIANT_BOOL Status) {      

		if (Status == VARIANT_TRUE) {

			_tprintf(_T("Mute on\n"));

		} else {

			_tprintf(_T("Mute off\n"));

		}

	}

	void __stdcall MessageStatus(IChatMessage* pMessage, TChatMessageStatus Status) {

		_tprintf(_T("Message id = %d, status %d\n"), pMessage->GetId(), Status);
		_bstr_t body = pMessage->GetBody();
		_tprintf(_T("	body - %s\n"), (LPCTSTR)body);
	}

	void __stdcall MessageHistory(BSTR Username) {

		_tprintf(_T("Message history changed %s\n"), (LPCTSTR)_bstr_t(Username));

	}

private:
	SkypeEnv *m_pSkypeEnv;

};

#endif //_SKYPE_EVENTS_H_
